﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.Threading;

namespace ManipulateFormProperty
{
    class Program
    {
        static void Main(string[] args)
        {

            string filename = "..\\..\\..\\AppTest\\bin\\debug\\apptest.exe";
            string formname = "AppTest.Form1";

            Form form = Launchapp(filename, formname);
            System.Drawing.Point p = new System.Drawing.Point(52, 99);

            Console.WriteLine("click any key and the window will change location.");
            Console.ReadLine();

            DSetFormPropertyValue d = new DSetFormPropertyValue(SetFormPropertyValue);
            object[] o = new object[] {form,"Location",p };

            if (form.InvokeRequired)
            {
                form.Invoke(d, o);
            }

            Console.WriteLine("change the title");
            Console.ReadLine();
            o = new object[] {form,"Text","Hello world" };

            if (form.InvokeRequired)
            {
                form.Invoke(d, o);
            }
            Console.ReadLine();
            
        }

        private static void SetFormPropertyValue(Form f, string propertyname,object newvalue)
        {
            Type t = f.GetType();
            PropertyInfo pi = t.GetProperty(propertyname);
            pi.SetValue(f, newvalue, null);
        }

        private delegate void DSetFormPropertyValue(Form f, string propertyname,object newvalue);


        private static Form Launchapp(string filename, string formname)
        {
            Assembly assembly = Assembly.LoadFrom(filename);
            Type t = assembly.GetType(formname);
            Form f = (Form)assembly.CreateInstance(t.FullName);

            AppState aps = new AppState(f);
            ThreadStart ts = new ThreadStart(aps.AppRun);
            Thread thread = new Thread(ts);
            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();

            return f;
        }
    }


    class AppState
    {
        private Form form;
        public AppState(Form form)
        {
            this.form = form;
        }

        public void AppRun()
        {
            Application.Run(form);
        }
    }
}
